/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.ages.entity

import com.ages.graphics.Sprite
import com.ages.input.SKeyboard
import java.awt.event.ActionEvent
import java.awt.event.ActionListener
import javax.media.opengl.GL
import com.ages.graphics.AnimatedSprite
import com.ages.graphics.GLDraw
import scala.collection.mutable.ArrayBuffer
import scala.collection.mutable.HashMap
import java.awt.event.KeyEvent._
import com.ages.input.SKeyboard
import com.ages.math.Vector3D
import com.ages.math.Vector

object Joint{
  val spr = new AnimatedSprite("/com/ages/test/res/skeleton_test.png")
//  val spr2 = new Sprite("/com/ages/test/res/fly1.png",1,1,1)
  var focusJoint:Joint =_
}

class Joint(name:String,frameNum:Int) extends Actor with ActionListener{
  
  var keys:SKeyboard =_
  val map = new HashMap[String,Joint]()
  val children = new ArrayBuffer[Joint]()
  map += toString -> this
  var rot = 0
  var offset:Vector = Vector3D(0,0,0)

  def getName = name

  def addKeys(k:SKeyboard){
    keys = k
    for(c <- flatList)
      c.keys = k
  }

  def flatList:List[Joint] = {
    var list:List[Joint] = List()
    for(c <- children)
    {
      list = c.flatList++list
    }
    this::list
  }
  def addJoint(j:Joint){
    children += j
    for(jj<-j.flatList)
    {
      if(map.contains(jj.toString))
        throw new RuntimeException("Joint already exists:"+jj)
      map += jj.toString -> jj
    }
  }
  def getChildrenDeep:List[Joint] = {
    var list:List[Joint] = List()
    for(c <- children)
    {
      list = c::c.getChildrenDeep++list
    }
    list
  }

  def removeJoint(j:Joint)//TODO:FINISH THIS METHOD, IT WONT WORK YET!
  {
    if(!(children.contains(j) && map.contains(j.toString)))
      throw new RuntimeException("Cannot remove joint, it doesnt exist..."+j)
    children -= j
    map.remove(j.toString)
      
  }

  def refreshMap{
    for(x<-getChildrenDeep)
    {
      if(!map.contains(x.getName))
        map += x.getName -> x
    }
  }
  
  def actionPerformed(e:ActionEvent)
  {
    refreshMap //make sure every child has been added to the map!
    println(e)
    println(e.getModifiers)
    println(e.getActionCommand,map(e.getActionCommand))
    Joint.focusJoint = map(e.getActionCommand)

    if(name.equals("pelvis"))
      {
        printXMLTags
      }
  }

  def think(){

    
    for(j<-children)
      j.think
    if(Joint.focusJoint==this)
    {
      if(keys.get(VK_SPACE))
      {
        println(this,"pos:"+pos,"offset:"+offset,"rot:"+rot,children)
      }

      if(keys.get(VK_UP))
        pos = pos plus Vector3D(0,1,0)
      if(keys.get(VK_DOWN))
        pos = pos plus Vector3D(0,-1,0)
      if(keys.get(VK_RIGHT))
        pos = pos plus Vector3D(1,0,0)
      if(keys.get(VK_LEFT))
        pos = pos plus Vector3D(-1,0,0)

      if(keys.get(VK_F))
        rot = if(rot>=360) 0 else rot+1
      if(keys.get(VK_G))
        rot = if(rot<= -360) 0 else rot-1

      if(keys.get(VK_W))
        offset = offset plus Vector3D(0,1,0)
      if(keys.get(VK_S))
        offset = offset plus Vector3D(0,-1,0)
      if(keys.get(VK_D))
        offset = offset plus Vector3D(1,0,0)
      if(keys.get(VK_A))
        offset = offset plus Vector3D(-1,0,0)

    }
//    if(name.equals("pelvis"))
//      println(pos)
  }

  def draw(gl:GL)
  {
    gl.glPushMatrix
    gl.glTranslated(pos.X,pos.Y,pos.Z)

    gl.glEnable(GL.GL_BLEND)
    
    if(Joint.focusJoint==this)
      gl.glColor4d(1,1,1,0.5)
    else
      gl.glColor4d(1,1,1,1)
    gl.glRotated(rot,0,0,1)
    gl.glPushMatrix
    gl.glTranslated(offset.X,offset.Y,offset.Z)
    Joint.spr.drawElement(gl, "idle", frameNum)
//    Joint.spr2.drawWithoutDisplaylist(gl,0,0)
    gl.glPopMatrix
    var j= 0
    for(child <- children)
    {
      gl.glPushMatrix
      for(c <- children)
      {
        val cp = child.pos
        gl.glColor4d(1,0,0,1)
        gl.glLineWidth(6)
        gl.glBegin(GL.GL_LINES)
        gl.glVertex2d(0,0)
        gl.glVertex2d(cp.X,cp.Y)
        gl.glEnd
      }
      gl.glPopMatrix

      child.draw(gl)
    }
    gl.glPopMatrix


  }

  override def toString = name

  def printXMLTags{
    printXML("")
  }
  private def printXML(tabs:String){
    val hasChildren = children.length!=0

    var tag ="<joint "
    tag += "name=\""+name+"\" frame=\""+frameNum+"\" "
    tag += "offset=\""+offset+"\" "
    tag += "pos=\""+pos+"\""
    tag += (if(!hasChildren)"\\" else "")+">\n"
//    print(tabs+"<joint name=\""+name+"\" frame=\""+frameNum+"\""+(if(!hasChildren)"\\" else "")+">\n")
    print(tabs+tag)
    for(x<-children)
    {
      x.printXML(tabs+"\t")
    }
    if(hasChildren)
      print(tabs+"</joint>\n")
  }
}


